/**
 * File Name: Dier.java
 *
 * Date: 18/12/2009
 *
 * Copyright (c) 2006 Michael LaLena. All rights reserved.  (www.lalena.com)
 * Permission to use, copy, modify, and distribute this Program and its documentation,
 *  if any, for any purpose and without fee is hereby granted, provided that:
 *   (i) you not charge any fee for the Program, and the Program not be incorporated
 *       by you in any software or code for which compensation is expected or received;
 *   (ii) the copyright notice listed above appears in all copies;
 *   (iii) both the copyright notice and this Agreement appear in all supporting documentation; and
 *   (iv) the name of Michael LaLena or lalena.com not be used in advertising or publicity
 *          pertaining to distribution of the Program without specific, written prior permission.
 */
package model;

import java.awt.*;

/**
 * Afgeleide klasse van AquariumObject
 * Deze klasse bevat het standaard gedrag en eigenschappen van bewegende dieren
 *
 * @author Michiel Declercq
 * @author Stijn Delbeke
 * @author Dieter Deriemaeker
 * @author Gregory Nickmans
 *
 * @author Michael LaLena
 *
 */
public abstract class Dier extends AquariumObject {

    /**
     * De richting van het dier in graden
     */
    private int currentTheta;

    /**
     * Snelheid van het dier
     */
    private double currentSpeed;

    /**
     * Het maximum aantal graden dat het dier in 1 keer mag draaien
     */
    private int maxTurnTheta;

    /**
     * Geeft de actuele snelheid terug
     * @return double
     */
    public double getCurrentSpeed() {
        return currentSpeed;
    }

    /**
     * Geeft de actuele hoek terug in graden
     * @return int
     */
    public int getCurrentTheta() {
        return currentTheta;
    }

    /**
     * Stelt de actuele snelheid bij
     * @param currentSpeed Nieuwe snelheid
     */
    public void setCurrentSpeed(double currentSpeed) {
        this.currentSpeed = currentSpeed;
    }

    /**
     * Stelt de actuele hoek bij
     * @param currentTheta Nieuwe hoek in graden
     */
    public void setCurrentTheta(int currentTheta) {
        this.currentTheta = currentTheta;
    }

    /**
     * Geeft de maximale hoek terug die het dier kan uitvoeren
     *
     * @return int
     */
    public int getMaxTurnTheta() {
        return maxTurnTheta;
    }

    /**
     * Stelt de maximale hoek in die het dier kan maken
     *
     * @param  theta Nieuwe hoek in graden
     */
    public void setMaxTurnTheta(int theta) {
        maxTurnTheta = theta;
    }

    /**
     * Constructor
     *
     * @param  x x-coördinaat
     * @param  y y-coördinaat
     * @param  dim Grootte van het dier
     * @param  theta De beginhoek van het dier
     * @param  kleur De kleur van het dier
     */
    public Dier(int x, int y, Dimension dim, int theta, Color kleur) {
        super(x, y, dim, kleur);
        currentTheta = theta;
    }

    /**
     * Beweegt het dier
     * @param nieuweRichting De richting waarin het object moet bewegen
     */
    @Override
    public void move(int nieuweRichting) {
        // bepaalt of het niet beter is om links of rechts te draaien
        int left = (nieuweRichting - currentTheta + 360) % 360;
        int right = (currentTheta - nieuweRichting + 360) % 360;
        // na de beslissing kijken of het mogelijk is om zoveel te draaien
        int thetaChange = 0;
        if (left < right) {
            // als het links is, dan is dit steeds kleinder dan de max. hoek
            thetaChange = Math.min(maxTurnTheta, left);
        }
        else {
            // rechts zorgt ervoor dat de hoek negatief moet zijn
            thetaChange = -Math.min(maxTurnTheta, right);
        }

        // Doe de richtingsverandering
        currentTheta = (currentTheta + thetaChange + 360) % 360;

        // Verplaats het dier volgens zijn actuele richting en snelheid
        location.x += (int) (currentSpeed * Math.cos(currentTheta * Math.PI / 180)) + map.width;
        location.x %= map.width;
        location.y -= (int) (currentSpeed * Math.sin(currentTheta * Math.PI / 180)) - map.height;
        location.y %= map.height;

        for (Stroming s : Stroming.getFlowAreas()) {
            Shape vorm = s.getShape();
            if (vorm.contains(new Point(location))) {
                location.x += s.getStrength() * Math.cos(s.getTheta());
                location.x %= map.width;
                location.y += s.getStrength() * Math.sin(s.getTheta());
                location.y %= map.height;
            }
        }
    }
}
